import { get } from 'lodash-es'

export function bindMethods<T extends object>(instance: T): void {
  const prototype = Object.getPrototypeOf(instance)
  const propertyNames = Object.getOwnPropertyNames(prototype)

  propertyNames.forEach((propertyName) => {
    const descriptor = Object.getOwnPropertyDescriptor(prototype, propertyName)
    const propertyValue = instance[propertyName as keyof T]

    if (
      typeof propertyValue === 'function'
      && propertyName !== 'constructor'
      && descriptor
      && !descriptor.get
      && !descriptor.set
    ) {
      instance[propertyName as keyof T] = propertyValue.bind(instance)
    }
  })
}

export const httpErrorMessage = {
  /** badRequest - 400 */
  badRequest: '请求参数错误, 请检查后重试',
  /** networkError */
  networkError: '网络异常，请检查您的网络连接后重试',
  /** unauthorized - 401 */
  unauthorized: '当前账号没有登录或者登录已失效，请重新登录',
  /** forbidden - 403 */
  forbidden: '禁止访问，您没有权限访问此资源',
  /** notFound - 404 */
  notFound: '请求的资源不存在',
  /** requestTimeout - 408 */
  requestTimeout: '请求超时，请稍后重试',
  internalServerError: '内部服务器错误，请稍后重试',
}

// code 或者 固定 key  对应的 错误 key
const httpErrorKeyMap = {
  400: 'badRequest',
  401: 'unauthorized',
  403: 'forbidden',
  404: 'notFound',
  408: 'requestTimeout',
  500: 'internalServerError',
  DEFAULT: 'internalServerError',
  networkError: 'networkError',
}

/**
 *
 * @param key 错误码 或者 错误 key
 * - `400` -> `badRequest`: 请求参数错误, 请检查后重试
 * - `401` -> `unauthorized`: 当前账号没有登录或者登录已失效，请重新登录
 * - `403` -> `forbidden`: 禁止访问，您没有权限访问此资源
 * - `404` -> `notFound`: 请求的资源不存在
 * - `408` -> `requestTimeout`: 请求超时，请稍后重试
 * - `500` -> `internalServerError`: 内部服务器错误，请稍后重试
 * - `networkError` -> `networkError`: 网络异常，请检查您的网络连接后重试
 * - `DEFAULT` -> `internalServerError`: 内部服务器错误，请稍后重试
 * @returns string 获取到的错误信息
 */
export function getHttpErrorMessage(key: number | string): string | undefined {
  if (!key) {
    return undefined
  }
  const _key = Number(key.toString().replace(API_CODE_PREFIX, ''))
  const errorKey = get(httpErrorKeyMap, _key, 'internalServerError')
  const res = get(httpErrorMessage, errorKey)
  return res
}
